/*
 * GenealogyTreeUtils.cpp
 *
 *  Created on: May 7, 2010
 *      Author: ctepx
 */

#include "GenealogyTreeUtils.h"
#include <string>
#include "db/DataSource.h"
#include "db/SqliteDataSource.h"
#include "db/DataSourceManager.h"
#include "tree/TreeIterator.h"
#include <sstream>

namespace etu {
namespace genealogy_tree {

#define DEFAULT_TREE_NAME "name"

using etu::db::DataSource;
using etu::db::SqliteDataSource;
using etu::db::DataSourceManager;
using etu::tree::TreeIterator;

void GenealogyTreeUtils::exportTree(const std::string& url, const std::string& treeName)
	throw(DataSourceException) {

	DataSource* srcDataSource = DataSourceManager::getDataSource();

	if(!srcDataSource->isGenealogyTreeExists(treeName)) {
		std::ostringstream oss;
		oss << "Источник данных не содержит таблицу под названием '"
				<< treeName << "'";
		throw DataSourceException(oss.str());
	}

	GenealogyTree* tree = srcDataSource->getGenealogyTree(treeName);
	DataSource* destDataSource = new SqliteDataSource(url);

	if(destDataSource->isGenealogyTreeExists(DEFAULT_TREE_NAME)) {
		destDataSource->deleteGenealogyTree(DEFAULT_TREE_NAME);
	}

	destDataSource->addGenealogyTree(DEFAULT_TREE_NAME, * tree);
	TreeIterator<const Person *>* it = tree->getIterator();

	while(it->hasNext()) {
		const Person* person = it->next();

		if(person->hasPhoto()
				&& destDataSource->isPhotoExists(* person)
				&& srcDataSource->isPhotoExists(* person)) {
			Photo* photo = srcDataSource->getPhoto(* person);
			destDataSource->addPhoto((Person *) person, * photo);
			delete photo;
		}
	}

	delete it;
	delete tree;
	delete destDataSource;
}

void GenealogyTreeUtils::importTree(const std::string& url, const std::string& treeName)
	throw(DataSourceException) {

	SqliteDataSource* srcDataSource = new SqliteDataSource(url);

	if(!srcDataSource->isGenealogyTreeExists(DEFAULT_TREE_NAME)) {
		delete srcDataSource;

		std::ostringstream oss;
		oss << "Файл '" << url << "; не содержит генеалогическое дерево";
		throw DataSourceException(oss.str());
	}

	DataSource* destDataSource = DataSourceManager::getDataSource();

	if(destDataSource->isGenealogyTreeExists(treeName)) {
		destDataSource->deleteGenealogyTree(treeName);
	}

	GenealogyTree* tree = srcDataSource->getGenealogyTree(DEFAULT_TREE_NAME);
	destDataSource->addGenealogyTree(treeName, * tree);

	TreeIterator<const Person *>* it = tree->getIterator();

	while(it->hasNext()) {
		const Person* person = it->next();

		if(person->hasPhoto()
				&& srcDataSource->isPhotoExists(* person)
				&& destDataSource->isPhotoExists(* person)) {
			Photo* photo = srcDataSource->getPhoto(* person);
			destDataSource->addPhoto((Person *) person, * photo);
			delete photo;
		}
	}

	delete it;
	delete tree;
	delete srcDataSource;
}

}
}
